/*
 * Data.cpp
 *
 *  Created on: 13 mei 2013
 *      Author: Wietse
 */

#include "Data.h"

#include <iostream>
#include <ctime>

/**
 * Default constructor
 */
Data::Data()
{
	this->sourceType = UNKNOWN;
	this->senderID = 0;
	this->position = Position();

	// Set timestamp to now
	time_t t = time(0);
	struct tm *now = localtime(&t);
	this->timestamp = *now;
}

/**
 * Preferred constructor
 */
Data::Data(Component comp, int ID, Position pos, tm *time)
{
	this->sourceType = comp;
	this->senderID = ID;
	this->position = pos;

	//Store timestamp
	timestamp = *time;
}

/**
 * Default destructor
 */
Data::~Data()
{
	// TODO Auto-generated destructor stub
}

Component Data::getSourceType()
{
	return sourceType;
}

int Data::getSenderID()
{
	return senderID;
}

Position* Data::getStart()
{
	return &position;
}

tm* Data::getTimestamp()
{
	return &timestamp;
}

/**
 * Checks if the other Data object is newer then this object
 */
bool Data::isNewer(Data &other)
{
	// Calculate the time difference
	double deltaTime = difftime(mktime(&timestamp), mktime(other.getTimestamp()));

	// Check which Data object is newer
	if(deltaTime < 0)
	{
		return true;
	}

	return false;
}

/**
 * Print data to console
 */
void Data::printData()
{
	std::cout << "Data: ";
	printSourceType();
	std::cout << senderID 		<< std::endl;
	std::cout << "Position: " 	<< position.toString()	<< std::endl;
	std::cout << "Timestamp: "	<< timestamp.tm_year << '-'
			<< timestamp.tm_mon << '-'
			<< timestamp.tm_mday << ' '
			<< timestamp.tm_hour << ':'
			<< timestamp.tm_min << ':'
			<< timestamp.tm_sec
			<< std::endl;
}

/**
 * Print sourceType to output
 */
void Data::printSourceType()
{
	switch(sourceType)
	{
	case 	UNKNOWN:
		std::cout << "Unknown ";
		break;
	case	BASESTATION:
		std::cout << "Basestation ";
		break;
	case	QUADCOPTER:
		std::cout << "Quadcopter ";
		break;
	case	CRAWLER:
		std::cout << "Crawler ";
		break;
	}
}

/**
 * Write the Data to an output file
 */
void Data::outputData(std::ofstream& output)
{
	output << "Data: ";
	output << getIdentifier() << std::endl;
	output << "Start: " 	<< position.toString()	<< std::endl;
	output << "Timestamp: "	<< timestamp.tm_year << '-'
			<< timestamp.tm_mon << '-'
			<< timestamp.tm_mday << ' '
			<< timestamp.tm_hour << ':'
			<< timestamp.tm_min << ':'
			<< timestamp.tm_sec
			<< std::endl;
}

/**
 * Generate the complete identifier of this Data object (sourceType + ID)
 */
std::string Data::getIdentifier()
{
	std::string identifier;
	identifier.clear();

	switch(sourceType)
	{
	case 	UNKNOWN:
		identifier += "Unknown ";
		break;
	case	BASESTATION:
		identifier += "Basestation ";
		break;
	case	QUADCOPTER:
		identifier += "Quadcopter ";
		break;
	case	CRAWLER:
		identifier += "Crawler ";
		break;
	}
	identifier += intToString(senderID);

	return identifier;
}

/**
 * Convert an int to a std::string
 */
std::string Data::intToString(int number)
{
	std::stringstream result;
	result << number;
	return result.str();
}

// Check if the data has expired
bool Data::isExpired(Position *currentPos)
{
	// Retrieve current time
	time_t t = time(0);
	struct tm *now = localtime(&t);

	// Calculate the elapsed time since sending the data
	double deltaTime = difftime(mktime(now), mktime(&timestamp));

	//ADD a ratio to DATA_CONSERVATION, so data that is further away expires slower
	//double ratio = position.distance(currentPos)/(40);
	double conservationTime = DATA_CONSERVATION; //+(DATA_CONSERVATION*ratio);

	//std::cout << "Distance = " << position.distance(currentPos) << ", conservationTime = " << conservationTime << std::endl;

	// Check if the elapsed time is too big
	if(deltaTime > conservationTime)
	{
		return true;
	}
	return false;
}



